<template>
    <div>
        <div style="margin: 20px 100px;">
            <button @click="exportModel">导入模型</button>
            <button @click="setRedLight">红色灯球</button>
        </div>
        <div id="webgl3"></div>
    </div>
</template>

<script setup>
import { onMounted } from 'vue';
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'

/** 创建场景对象Scene*/
let scene = new THREE.Scene();
let modelGroups = [];

/** 光源设置 */
// 平行光
const directionalLights = new THREE.DirectionalLight(0xffffff, 1);
directionalLights.position.set(200, 200, -200);
scene.add(directionalLights);
// const dirLightHelper = new THREE.DirectionalLightHelper(directionalLights, 5,0xff0000);
// scene.add(dirLightHelper);
// var ambientLights = new THREE.AmbientLight(0xffffff, 0.4);
// scene.add(ambientLights);

/** 相机设置 */
let c_width = 1200;
let c_height = 800;
// let c_k = c_width/c_height;
// let c_s = 200; // 三维场景显示范围控制系数，系数越大，显示的范围越大
// let camera = new THREE.OrthographicCamera(-c_s*c_k, c_s*c_k, c_s, -c_s, 1, 2000);//正交投影相机对象,地图时使用
let camera = new THREE.PerspectiveCamera(); //透视相机，模拟人眼
camera.position.set(-250, 250, 0);// 设置相机位置
camera.lookAt(0, 0, 0);//指向坐标原点
// camera.lookAt(scene.position); //设置相机方向（指向的场景对象）
/**创建的渲染对象 */
var renderer = new THREE.WebGLRenderer();

onMounted(()=>{
    initRender();
    // setAxisHelper();

    // exportModel();
})

//渲染
const initRender = ()=>{
    renderer.setSize(c_width, c_height); //设置渲染区域尺寸
    renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
    document.getElementById('webgl3').appendChild(renderer.domElement);
    doRendering();
    new OrbitControls(camera, renderer.domElement);//创建控件对象
}
//鼠标操作后渲染
const doRendering = ()=>{
    renderer.render(scene,camera);//执行渲染操作
    requestAnimationFrame(doRendering);
}
// 辅助坐标系
const setAxisHelper = ()=>{
    var axisHelper = new THREE.AxesHelper(450); // 参数450表示坐标系大小，可以根据场景大小去设置
    scene.add(axisHelper);
}

//导入gltf模型
const exportModel = ()=>{
    const loader = new GLTFLoader();
    loader.load('/static/model/Model1.glb', function ( gltf ) {
        // console.log('控制台查看加载gltf文件返回的对象结构',gltf);
        console.log('gltf对象场景属性',gltf.scene);
        gltf.scene.scale.set(16,16,16);//网格模型缩放
        // 返回的场景对象gltf.scene插入到threejs场景中
        gltf.scene.children[1].material.color.set(0xffffff)
        // gltf.scene.children[2].material.color.set(0xffffff)
        scene.add( gltf.scene );

        const obj = gltf.scene.getObjectByName('灯球');
        // console.log('obj', obj); //控制台查看返回结果
        // obj.material.color.set(0xff0000);
        modelGroups.push(obj)
        
    })
}

let redAnimationFrame = null;
const setRedLight = ()=>{
    let modelObj = modelGroups[0]
    modelObj.material.color.set(0xff0000);
    modelObj.scale.set(2,2,2)

    // var redPoint = new THREE.PointLight(0xff0000); //点光源
    // redPoint.position.set(modelObj.position); //光源位置
    // scene.add(redPoint);


    const clock = new THREE.Clock();
    const animate = () => {
        const elapsedTime = clock.getElapsedTime();
        modelObj.rotation.y = elapsedTime;
        renderer.render(scene, camera);
        redAnimationFrame = requestAnimationFrame(animate);
    };
    animate();
}

renderer.domElement.addEventListener('click', function (event) {
    // .offsetY、.offsetX以canvas画布左上角为坐标原点,单位px
    const px = event.offsetX;
    const py = event.offsetY;
    //屏幕坐标px、py转WebGL标准设备坐标x、y
    //width、height表示canvas画布宽高度
    const x = (px / c_width) * 2 - 1;
    const y = -(py / c_height) * 2 + 1;
    //创建一个射线投射器`Raycaster`
    const raycaster = new THREE.Raycaster();
    //.setFromCamera()计算射线投射器`Raycaster`的射线属性.ray
    // 形象点说就是在点击位置创建一条射线，射线穿过的模型代表选中
    raycaster.setFromCamera(new THREE.Vector2(x, y), camera);
    //.intersectObjects([mesh1, mesh2, mesh3])对参数中的网格模型对象进行射线交叉计算
    // 未选中对象返回空数组[],选中一个对象，数组1个元素，选中两个对象，数组两个元素
    const intersects = raycaster.intersectObjects([modelGroups[0]]);
    // intersects.length大于0说明，说明选中了模型
    if (intersects.length > 0) {
        if(confirm('还原？') == true){
            let modelObj = modelGroups[0]
            modelObj.scale.set(0.3,0.3,0.3)
            modelObj.material.color.set(0xffff00);
            redAnimationFrame && cancelAnimationFrame(redAnimationFrame)
        }else{
            alert('已经取消还原')
        }
    }
})

</script>

<style lang="scss" scoped>

</style>